﻿/***********************************************************************
 * <copyright file="BaseListUserControl.cs" company="BUCA JSC">
 * -->    Copyright (C) statement. All right reserved
 * </copyright>
 * 
 * Created:   LinhMC
 * Email:    linhmc@buca.vn
 * Website:
 * Create Date: Monday, February 10, 2014
 * Usage: 
 * 
 * RevisionHistory: 
 * Date         Author               Description 
 * 
 * ************************************************************************/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;
using WindowsForms.AOnline.Model.BusinessObjects.Report;
using WindowsForms.AOnline.Presenter.Report;
using WindowsForms.AOnline.Report.ReportClass;
using WindowsForms.AOnline.Session;
using WindowsForms.AOnline.View.Report;
using WindowsForms.AOnline.WindowsForm.FormBase;
using WindowsForms.AOnline.WindowsForm.FormBase.PropertyGrid;
using WindowsForms.AOnline.WindowsForm.Resources;
using DevExpress.Data;
using DevExpress.Utils;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Columns; 


namespace WindowsForms.AOnline.WindowsForm.BaseUserControls
{
    public partial class BaseListUserControl : XtraUserControl, IReportView
    {
        private readonly ReportListPresenter _reportListPresenter;
        private List<ReportListModel> _reportList;

        #region Variables

        /// <summary>
        /// Action Mode
        /// </summary>
        public enum ActionModeEnum
        {
            AddNew = 0,
            Edit = 1,
            Delete = 2,
            None = 3
        }
        /// <summary>
        /// The e action mode
        /// </summary>
        public ActionModeEnum ActionMode;
        /// <summary>
        /// The columns collection
        /// </summary>
        public List<XtraColumn> ColumnsCollection = new List<XtraColumn>();
        /// <summary>
        /// The primary key value
        /// </summary>
        public string PrimaryKeyValue;

        /// <summary>
        /// The current page
        /// </summary>
        public static int CurrentPage = 1;

        public static int TotalPage = 1;  

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the form detail.
        /// </summary>
        /// <value>
        /// The form detail.
        /// </value>
        [Category("BaseProperty")]
        public string FormDetail { get; set; }

        /// <summary>
        /// Gets or sets the namespace form.
        /// </summary>
        /// <value>
        /// The namespace form.
        /// </value>
        [Category("BaseProperty")]
        public string NamespaceForm { get; set; }

        /// <summary>
        /// Gets or sets the table primary key.
        /// </summary>
        /// <value>
        /// The table primary key.
        /// </value>
        [Category("BaseProperty")]
        public string TablePrimaryKey { get; set; }

        /// <summary>
        /// Gets or sets the form caption.
        /// </summary>
        /// <value>
        /// The form caption.
        /// </value>
        [Category("BaseProperty")]
        public string FormCaption { get; set; }

        /// <summary>
        /// Gets or sets the row selected.
        /// </summary>
        /// <value>
        /// The row selected.
        /// </value>
        [Category("BaseProperty")]
        public int RowSelected { get; set; }

        /// <summary>
        /// Gets or sets the report identifier.
        /// </summary>
        /// <value>
        /// The report identifier.
        /// </value>
        [Category("BaseProperty")]
        public string ReportID { get; set; }

        #endregion

        #region Functions

        /// <summary>
        /// Initializes the layout.
        /// </summary>
        private void InitializeLayout()
        {
            Text = FormCaption;
            ActionMode = ActionModeEnum.None;
            grdList.Focus();
        }

        /// <summary>
        /// Loads the data.
        /// </summary>
        protected void LoadData()
        {
            try
            {
                gridView.BeginUpdate();
                LoadDataIntoGrid(CurrentPage);
                LoadGridLayout();
                SetGridNumericFormat();
                grdList.ForceInitialize();
                if (CurrentPage <= TotalPage)
                {
                    lblPage.Text = @"Trang " + CurrentPage.ToString() + @"/" + TotalPage.ToString();
                }
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show(ex.Message, ResourceHelper.GetResourceValueByName("ResExceptionCaption"));
                gridView.EndUpdate();
            }
            finally
            {
                gridView.EndUpdate();
                ActionMode = ActionModeEnum.None;
            }
        }

        /// <summary>
        /// Loads the grid layout.
        /// </summary>
        private void LoadGridLayout()
        {
            if (ColumnsCollection != null)
            {
                foreach (var column in ColumnsCollection)
                {
                    if (column.ColumnVisible)
                    {

                        gridView.Columns[column.ColumnName].Caption = column.ColumnCaption;
                        gridView.Columns[column.ColumnName].AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center;
                        gridView.Columns[column.ColumnName].VisibleIndex = column.ColumnPosition;
                        gridView.Columns[column.ColumnName].Width = column.ColumnWith;
                        gridView.Columns[column.ColumnName].AppearanceCell.TextOptions.HAlignment = column.Alignment;
                        gridView.Columns[column.ColumnName].UnboundType = column.ColumnType;
                        gridView.Columns[column.ColumnName].ColumnEdit = column.RepositoryControl;
                        gridView.Columns[column.ColumnName].ToolTip = column.ToolTip;
                    }
                    else
                        gridView.Columns[column.ColumnName].Visible = false;
                }
            }
        }

        /// <summary>
        /// Sets the row selected.
        /// </summary>
        /// <param name="rowHandler">The row handler.</param>
        private void SetRowSelected(int rowHandler = 0)
        {
            gridView.OptionsSelection.EnableAppearanceFocusedRow = true;
            gridView.OptionsSelection.EnableAppearanceFocusedCell = false;
            if (gridView.RowCount > 0)
                gridView.FocusedRowHandle = rowHandler;
        }

        /// <summary>
        /// Gets the row value selected.
        /// </summary>
        public void GetRowValueSelected()
        {
            try
            {
                if (gridView.DataSource != null)
                {
                    var rowHandle = gridView.FocusedRowHandle;
                    if (!DesignMode)
                    {
                        if (ActionMode == ActionModeEnum.None || ActionMode == ActionModeEnum.Delete)
                            PrimaryKeyValue = gridView.GetRowCellValue(rowHandle, TablePrimaryKey) != null
                                                  ? gridView.GetRowCellValue(rowHandle, TablePrimaryKey).ToString()
                                                  : null;
                    }
                }
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show(ex.Message, ResourceHelper.GetResourceValueByName("ResExceptionCaption"));
            }
        }

        /// <summary>
        /// Shows the form detail.
        /// </summary>
        private void ShowFormDetail()
        {
            try
            {
                using (var frmDetail = GetFormDetail())
                {
                    frmDetail.ActionMode = (FrmXtraBaseCategoryDetail.ActionModeEnum)ActionMode;
                    frmDetail.KeyValue = frmDetail.ActionMode == FrmXtraBaseCategoryDetail.ActionModeEnum.AddNew ? null : PrimaryKeyValue;
                    frmDetail.PostKeyValue += FrmDetail_PostKey;
                    if (ActionMode == ActionModeEnum.AddNew)
                    {
                        ListBindingSource.AddNew();
                        ListBindingSource.MoveLast();
                    }
                    frmDetail.BindingSourceDetail = ListBindingSource;
                    if (frmDetail.ShowDialog() == DialogResult.OK) { }
                }
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show(ex.Message, ResourceHelper.GetResourceValueByName("ResExceptionCaption"), MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Gets the form detail.
        /// </summary>
        /// <returns></returns>
        private FrmXtraBaseCategoryDetail GetFormDetail()
        {
            try
            {
                var typeOfForm = Assembly.GetExecutingAssembly().GetType(NamespaceForm + "." + FormDetail);
                return typeOfForm != null ? (FrmXtraBaseCategoryDetail)Activator.CreateInstance(typeOfForm) : null;
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show(ex.Message, ResourceHelper.GetResourceValueByName("ResExceptionCaption"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                return null;
            }
        }

        /// <summary>
        /// Sets the row after update.
        /// </summary>
        protected void SetRowAfterUpdate()
        {
            try
            {
                if (gridView.RowCount <= 0) return;
                var xtraColumn = gridView.Columns[TablePrimaryKey];
                for (int i = 0; i < gridView.RowCount; i++)
                {
                    var currentValue = gridView.GetRowCellValue(i, xtraColumn).ToString();
                    if (PrimaryKeyValue != currentValue) continue;
                    RowSelected = i; break;
                }
                SetRowSelected(RowSelected);
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show(ex.Message, ResourceHelper.GetResourceValueByName("ResExceptionCaption"));
            }
        }

        /// <summary>
        /// FRMs the detail_ post key.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="data">The data.</param>
        public void FrmDetail_PostKey(object sender, string data)
        {
            PrimaryKeyValue = data;
        }

        /// <summary>
        /// Refreshes the toolbar.
        /// </summary>
        protected virtual void RefreshToolbar()
        {
            barButtonEditItem.Enabled = gridView.RowCount > 0;
            barButtonDeleteItem.Enabled = gridView.RowCount > 0;
            barButtonPrintItem.Enabled = gridView.RowCount > 0;
        }

        /// <summary>
        /// Sets the grid numeric format.
        /// </summary>
        protected virtual void SetGridNumericFormat()
        {
            foreach (GridColumn oCol in gridView.Columns)
            {
                if (!oCol.Visible) continue;
                switch (oCol.UnboundType)
                {
                    case UnboundColumnType.Decimal:
                        oCol.DisplayFormat.FormatString = GlobalVariable.CurrencyDisplayString;
                        oCol.DisplayFormat.Format = Thread.CurrentThread.CurrentCulture.NumberFormat;
                        oCol.SummaryItem.SummaryType = SummaryItemType.Sum;
                        oCol.SummaryItem.DisplayFormat = GlobalVariable.CurrencyDisplayString;
                        oCol.SummaryItem.Format = Thread.CurrentThread.CurrentCulture.NumberFormat;
                        break;
                    case UnboundColumnType.Integer:
                        oCol.DisplayFormat.FormatString = GlobalVariable.NumericDisplayString;
                        oCol.DisplayFormat.Format = Thread.CurrentThread.CurrentCulture.NumberFormat;
                        break;
                    case UnboundColumnType.DateTime:
                        oCol.DisplayFormat.FormatString = Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern;
                        oCol.DisplayFormat.Format = Thread.CurrentThread.CurrentCulture.DateTimeFormat;
                        break;
                }
            }
        }

        #endregion

        #region Functions overrides
        /// <summary>
        /// Loads the data into grid.
        /// </summary>
        protected virtual void LoadDataIntoGrid(int Page)
        {
        }

        /// <summary>
        /// Deletes the grid.
        /// </summary>
        protected virtual string DeleteGrid()
        {
            return "";
        }

        /// <summary>
        /// Adds the data.
        /// </summary>
        protected virtual void AddData()
        {
            ActionMode = ActionModeEnum.AddNew;
            ShowFormDetail();
            LoadData();
        }

        /// <summary>
        /// Edits the data.
        /// </summary>
        protected virtual void EditData()
        {
            ActionMode = ActionModeEnum.Edit;
            ShowFormDetail();
            LoadData();
        }

        /// <summary>
        /// Prints the data.
        /// </summary>
        protected virtual void PrintData()
        {
            try
            {
                ActionMode = ActionModeEnum.None;
                Cursor.Current = Cursors.WaitCursor;
                var reportHelper = new ReportHelper();
                _reportList = _reportListPresenter.GetAllReportList();
                reportHelper.ReportLists = _reportList;
                reportHelper.PrintPreviewReport(null, ReportID, false);
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show(ex.ToString(), "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        /// <summary>
        /// Helps this instance.
        /// </summary>
        protected virtual void Help()
        {

        }


        #endregion

        #region Events

        /// <summary>
        /// Initializes a new instance of the <see cref="BaseListUserControl"/> class.
        /// </summary>
        public BaseListUserControl()
        {
            InitializeComponent();
            _reportListPresenter = new ReportListPresenter(this);
        }

        /// <summary>
        /// Handles the Load event of the BaseListUserControl control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        private void BaseListUserControl_Load(object sender, EventArgs e)
        {
            InitializeLayout();
            LoadData();
            SetRowSelected(RowSelected);
            GetRowValueSelected();
            RefreshToolbar();
        }

        /// <summary>
        /// Handles the FocusedRowChanged event of the gridView control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs"/> instance containing the event data.</param>
        private void gridView_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
        {
            GetRowValueSelected();
        }

        /// <summary>
        /// Handles the DoubleClick event of the grdList control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        private void grdList_DoubleClick(object sender, EventArgs e)
        {
            EditData();
            SetRowAfterUpdate();
            GetRowValueSelected();
        }

        /// <summary>
        /// Handles the ItemClick event of the barToolManager control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="DevExpress.XtraBars.ItemClickEventArgs"/> instance containing the event data.</param>
        private void barToolManager_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            switch (e.Item.Name)
            {
                case "barButtonAddNewItem":
                    AddData();
                    SetRowAfterUpdate();
                    GetRowValueSelected();
                    break;
                case "barButtonEditItem":
                    EditData();
                    SetRowAfterUpdate();
                    GetRowValueSelected();
                    break;
                case "barButtonDeleteItem":
                    try
                    {
                        ActionMode = ActionModeEnum.Delete;
                        var result = XtraMessageBox.Show(ResourceHelper.GetResourceValueByName("ResDeleteContent"),
                                                         ResourceHelper.GetResourceValueByName("ResDeleteCaption"),
                                                         MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                        if (result == DialogResult.OK)
                        {
                            var errorMess = DeleteGrid();
                            if (errorMess == null)
                            {
                                XtraMessageBox.Show(ResourceHelper.GetResourceValueByName("ResDeleteResult"),
                                                 ResourceHelper.GetResourceValueByName("ResDeleteCaption"),
                                                 MessageBoxButtons.OK, MessageBoxIcon.Information);

                            }
                            else
                            {
                                XtraMessageBox.Show(errorMess, ResourceHelper.GetResourceValueByName("ResExceptionCaption"));
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                    
                    }
                    finally
                    {
                        LoadData();
                        SetRowSelected();
                        GetRowValueSelected();
                    }
                    break;
                case "barButtonRefeshItem":
                    LoadData();
                    SetRowSelected();
                    GetRowValueSelected();
                    break;
                case "barButtonPrintItem":
                    PrintData();
                    break;
                case "barButtonHelpItem":
                    ActionMode = ActionModeEnum.None;
                    Help();
                    break;
            }
            RefreshToolbar();
        }

        #endregion

        #region IReportView Members

        public List<ReportListModel> ReportLists
        {
            get
            {
                return _reportList;
            }
            set
            {
                _reportList = value;
            }
        }

        #endregion

        private void btnPre_Click(object sender, EventArgs e)
        {
            CurrentPage = CurrentPage - 1;
            if (CurrentPage == 0)
            {
                CurrentPage = 1;
            }
            LoadData();
        }

        private void btnNext_Click(object sender, EventArgs e)
        {
            CurrentPage = CurrentPage + 1;
            if (CurrentPage > TotalPage)
            {
                CurrentPage = TotalPage;
            }
            LoadData();
        }

        private void btnFirst_Click(object sender, EventArgs e)
        {

            CurrentPage = 1;
            LoadData();
        }

        private void btnLast_Click(object sender, EventArgs e)
        {
            CurrentPage = TotalPage;
            LoadData();
        }
    }
}